/*
 * @Author: your name
 * @Date: 2021-03-28 20:28:46
 * @LastEditTime: 2021-03-28 20:37:49
 * @LastEditors: your name
 * @Description: In User Settings Edit
 * @FilePath: \jun-bang-sheng-chan-guan-li-xi-tongc:\Users\chenxin\Documents\WeChat Files\wxid_44w4zmigvyek22\FileStorage\File\2021-03\menu.js
 */
/**
 * 该插件可根据菜单配置自动生成 ANTD menu组件
 * menuOptions示例：
 * [
 *  {
 *    name: '菜单名称',
 *    path: '菜单路由',
 *    meta: {
 *      icon: '菜单图标',
 *      invisible: 'boolean, 是否不可见, 默认 false',
 *    },
 *    children: [子菜单配置]
 *  },
 *  {
 *    name: '菜单名称',
 *    path: '菜单路由',
 *    meta: {
 *      icon: '菜单图标',
 *      invisible: 'boolean, 是否不可见, 默认 false',
 *    },
 *    children: [子菜单配置]
 *  }
 * ]
 *
 * i18n: 国际化配置。组件默认会根据 options route配置的 path 和 name 生成英文以及中文的国际化配置，如需自定义或增加其他语言，配置
 * 此项即可。如：
 * i18n: {
 *   CN: {dashboard: {name: '监控中心'}}
 *   HK: {dashboard: {name: '監控中心'}}
 * }
 **/
import Menu from "ant-design-vue/es/menu";
import Icon from "ant-design-vue/es/icon";
import "@/utils/Objects";

const { Item, SubMenu } = Menu;

export default {
  name: "IMenu",
  props: {
    options: {
      type: Array,
      required: true,
    },
    theme: {
      type: String,
      required: false,
      default: "dark",
    },
    mode: {
      type: String,
      required: false,
      default: "inline",
    },
    collapsed: {
      type: Boolean,
      required: false,
      default: false,
    },
    i18n: Object,
  },
  data() {
    return {
      openKeys: [],
      selectedKeys: [],
      cachedOpenKeys: [],
      routerCache: [],
    };
  },
  computed: {
    rootSubmenuKeys: (vm) => {
      let keys = [];
      vm.options.forEach((item) => {
        keys.push(item.path);
      });
      return keys;
    },
    menuTheme() {
      return this.theme == "light" ? this.theme : "dark";
    },
  },
  beforeMount() {
    let CN = this.generateI18n(new Object(), this.options, "name");
    let US = this.generateI18n(new Object(), this.options, "path");
    this.$i18n.setLocaleMessage("CN", CN);
    this.$i18n.setLocaleMessage("US", US);
    if (this.i18n) {
      Object.keys(this.i18n).forEach((key) => {
        this.$i18n.mergeLocaleMessage(key, this.i18n[key]);
      });
    }
    this.$emit("i18nComplete", this.$i18n._getMessages());
  },
  created() {
    this.updateMenu();
    this.formatOptions(this.options, ""); // 格式化
  },
  watch: {
    collapsed(val) {
      if (val) {
        this.cachedOpenKeys = this.openKeys;
        this.openKeys = [];
      } else {
        this.openKeys = this.cachedOpenKeys;
      }
    },
    $route: function() {
      this.updateMenu();
    },
  },
  mounted(){
    //新增token验证--------
     let userToken = localStorage.getItem("zhqh-pro-token");
       if (userToken == null) {
         this.$router.push("/login");
       }
     //-----------------token验证结束----------------------
   },
  methods: {
    renderIcon: function(h, icon) {
      return !icon || icon == "none"
        ? null
        : h(Icon, { props: { type: icon } });
    },
    // 渲染最后最后一级
    renderMenuItem: function(h, menu) {
      // console.log('menu:::', menu);
      if (menu.notShow) return; // 禁止某些路由在左侧菜单栏中进行显示
      const spanText = this.$t(
        menu.fullPath.substring(1).replace(new RegExp("/", "g"), ".") + ".name"
      );

      return h(Item, { key: menu.fullPath }, [
        h("router-link", { props: { to: menu.fullPath } }, [
          this.renderIcon(h, menu.meta ? menu.meta.icon : "none"),
          h("span", [spanText]),
        ]),
      ]);
    },
    // 渲染有孩子的爸爸级别
    renderSubMenu: function(h, menu) {
      if (menu.notShow) return; // 禁止某些路由在左侧菜单栏中进行显示
      let this_ = this;
      let subItem = [
        h("span", { slot: "title" }, [
          this.renderIcon(h, menu.meta ? menu.meta.icon : "none"), // 渲染图标
          h("span", [
            this.$t(
              menu.fullPath.substring(1).replace(new RegExp("/", "g"), ".") +
                ".name"
            ),
          ]), // 渲染文字
        ]),
      ];
      let itemArr = [];
      menu.children.forEach(function(item) {
        itemArr.push(this_.renderItem(h, item));
      });
      return h(SubMenu, { key: menu.fullPath }, subItem.concat(itemArr));
    },
    renderItem: function(h, menu) {
      const meta = menu.meta;
      if (!meta || !meta.invisible) {
        let renderChildren = false;
        const children = menu.children;
        if (children != undefined) {
          for (let i = 0; i < children.length; i++) {
            const childMeta = children[i].meta;
            if (!childMeta || !childMeta.invisible) {
              renderChildren = true;
              break;
            }
          }
        }
        return menu.children && renderChildren
          ? this.renderSubMenu(h, menu)
          : this.renderMenuItem(h, menu);
      }
    },
    renderMenu: function(h, menuTree) {
      let this_ = this;
      let menuArr = [];
      let menuObj = {};
      let AloneArr = [];
      // console.log("对目录树进行唯一性检查");
      // console.log("目录树长度：", menuTree.length);
      menuTree.forEach((item, index) => {
        let key = item.fullPath;
        if (Object.prototype.hasOwnProperty.call(menuObj, key)) {
          menuObj[key].push(index);
        } else {
          menuObj[key] = [index];
          AloneArr.push(index);
        }
      });
      // console.log("检查后目录树长度：", AloneArr.length);
      let new_menuTre = AloneArr.map((item) => {
        return menuTree[item];
      });

      new_menuTre.forEach(function(menu, i) {
        menuArr.push(this_.renderItem(h, menu, "0", i));
      });
      return menuArr;
    },
    // ================
    // === 格式化函数 ===
    // ================
    formatOptions(options, parentPath) {
      let this_ = this;
      options.forEach((route) => {
        let isFullPath = route.path.substring(0, 1) == "/";
        route.fullPath = isFullPath
          ? route.path
          : parentPath + "/" + route.path;
        if (route.children) {
          this_.formatOptions(route.children, route.fullPath); // 递归
        }
      });
    },
    // SubMenu 展开/关闭的回调
    onOpenChange(openKeys) {
      const latestOpenKey = openKeys.find(
        (key) => this.openKeys.indexOf(key) === -1
      );
      if (this.rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
        this.openKeys = openKeys;
      } else {
        this.openKeys = latestOpenKey ? [latestOpenKey] : [];
      }
    },
    updateMenu() {
      let routes = this.$route.matched.concat();
      // console.log("xxxxxxxx", this.$route);
      const route = routes.pop();
      this.selectedKeys = [this.getSelectedKey(route)];
      let openKeys = [];
      routes.forEach((item) => {
        openKeys.push(item.path);
      });
      this.collapsed || this.mode === "horizontal"
        ? (this.cachedOpenKeys = openKeys)
        : (this.openKeys = openKeys);
    },
    getSelectedKey(route) {
      if (route.meta.invisible && route.parent) {
        return this.getSelectedKey(route.parent);
      }
      return route.path;
    },
    generateI18n(lang, options, valueKey) {
      options.forEach((menu) => {
        let keys = menu.fullPath
          .substring(1)
          .split("/")
          .concat("name");
        lang.assignProps(keys, menu[valueKey]);
        if (menu.children) {
          this.generateI18n(lang, menu.children, valueKey);
        }
      });
      return lang;
    },
  },
  render(h) {
    return h(
      Menu,
      {
        props: {
          theme: this.menuTheme,
          mode: this.$props.mode,
          openKeys: this.openKeys,
          selectedKeys: this.selectedKeys,
        },
        on: {
          openChange: this.onOpenChange,
          select: (obj) => {
            this.selectedKeys = obj.selectedKeys;
            this.$emit("select", obj);
          },
        },
      },
      this.renderMenu(h, this.options)
    );
  },
};
